package com.d5xx.hunters.events;

import com.d5xx.hunters.API.Hunter;
import com.d5xx.hunters.API.HunterGame;
import com.d5xx.hunters.API.HunterPlayer;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerPortalEvent;

public class PlayerPortal implements Listener {
    @EventHandler
    public void onPlayerPortal(PlayerPortalEvent event) {
        event.setCancelled(true);
        Player player = event.getPlayer();
        HunterPlayer gamer = Hunter.getHunterPlayer(player);

        if (gamer.getType().equals("lobby") || gamer.getType().equals("lobby-waiting")) { return; }

        World fromWorld = event.getFrom().getWorld();
        HunterGame game = Hunter.getGame(fromWorld);

        if (fromWorld == null) return;

        // 判断传送门是否为游戏中的传送门
        if (fromWorld.equals(game.getWorld())) {
            // 判断传送门类型
            if (event.getCause() == PlayerPortalEvent.TeleportCause.NETHER_PORTAL) { // 下界

                teleportToNether(game, player);

            } else if (event.getCause() == PlayerPortalEvent.TeleportCause.END_PORTAL) { // 末地

                player.teleport(game.getTheEnd().getSpawnLocation());

            }
        }
    }

    private void teleportToNether(HunterGame game, Player player) {
        Location netherLoc = getNetherPortal(convertToNether(player.getLocation(), game.getNether()));

        if (netherLoc != null) {
            player.teleport(netherLoc);
        }
    }

    private Location getNetherPortal(Location loc) {
        World world = loc.getWorld();
        int X = loc.getBlockX();
        int Y = loc.getBlockY();
        int Z = loc.getBlockZ();
        float yaw = loc.getYaw();

        // 遍历区域内的所有方块坐标
        if (world == null) return null;
        for (int offsetY = -16; offsetY <= 16; offsetY++) {
            for (int offsetX = -16; offsetX <= 16; offsetX++) {
                for (int offsetZ = -16; offsetZ <= 16; offsetZ++) {
                    int x = X + offsetX;
                    int y = Y + offsetX;
                    int z = Z + offsetZ;

                    // 获取当前方块
                    Block block = world.getBlockAt(x, y, z);
                    // 检查传送门是否存在
                    if (block.getType() == Material.NETHER_PORTAL) {
                        return block.getLocation();
                    }

                }
            }
        }
        createNetherPortal(loc);
        return loc;
    }

    private Location convertToNether(Location overworldLocation, World nether) {

        float yaw = overworldLocation.getYaw();
        if (overworldLocation.getYaw() <= 45 & overworldLocation.getYaw() > -45) yaw = 0;
        else if (overworldLocation.getYaw() >= 45 & overworldLocation.getYaw() < 135) yaw = 90;
        else if (overworldLocation.getYaw() >= 135 | overworldLocation.getYaw() <= -135) yaw = 180;

        Location loc = new Location(
                nether,
                Math.floor(overworldLocation.getX() / 8),
                30,
                Math.floor(overworldLocation.getZ() / 8),
                yaw,
                90
        );

        while (loc.getBlock().getType() != Material.AIR) {
            loc = loc.add(0, 1, 0);
        }

        return loc;
    }

    private void createNetherPortal(Location location) {
        switch ((int) location.getYaw()) {
            case 0:
            case 180:
            case -180:
                location.add(1, 0,0).subtract(0, 1, 0);

                // 创建地狱门
                for (int a = 0; a < 5; a++) {
                    for (int b = 0; b < 4; b++) {
                        location.clone().add(b, a, 0).getBlock().setType(Material.OBSIDIAN);
                    }
                }
                for (int a = 1; a < 5; a++) {
                    for (int b = 1; b < 4; b++) {
                        location.clone().add(b, a, 0).getBlock().setType(Material.NETHER_PORTAL);
                    }
                }

                break;

            case 90:
            case -90:
                location.add(0, 0, 1).subtract(0, 1, 0);

                // 创建地狱门
                for (int  a = 0; a < 5; a++) {
                    for (int b = 0; b < 4; b++) {
                        location.clone().add(0, a, b).getBlock().setType(Material.OBSIDIAN);
                    }
                }
                for (int a = 1; a < 5; a++) {
                    for (int b = 1; b < 4; b++) {
                        location.clone().add(0, a, b).getBlock().setType(Material.NETHER_PORTAL);
                    }
                }

                break;

        }
    }
}
